from flask import Blueprint, request, Request
from flask.scaffold import T_route
from flask_socketio import SocketIO
from src.common.R import R
from src.entry.Entrys import Page
from src.util.ParamUtil import formatParam
from src.util import JwtUtil

socket: SocketIO
blu = Blueprint('http-server', __name__)


# 路由装饰器

def route(rule: str, **options: any):
    from src.models.Menu import SysHandle
    from src.util.Log import logging
    methods = options.get('methods')
    if methods is None:
        methods = ['GET']

    for item in methods:
        r = SysHandle.hasHandleByPathMethod(rule, item)
        if not r:
            data = dict()
            data['name'] = options.get('name') or '未命名'
            data['status'] = options.get('status') or '1'
            data['log'] = options.get('log') or '0'
            data['path'] = rule
            data['method'] = item
            data['key'] = options.get('key') or 'sys'
            data['type'] = options.get('handle') or 'handle'
            SysHandle.addHandle(data)
            logging.info(f'新接口{rule}  {item}  已添加入数据库')

    options = formatParam(options, ['name'], ['methods'])

    def decorator(f: T_route) -> T_route:
        endpoint = options.pop("endpoint", None)
        blu.add_url_rule(rule, endpoint, f, **options)
        return f

    return decorator


# get 接口
def Get(rule: str, **options: any):
    options['methods'] = ['GET']
    return route(rule, **options)


# post 接口
def Post(rule: str, **options: any):
    options['methods'] = ['POST']
    return route(rule, **options)


# delete 接口
def Delete(rule: str, **options: any):
    options['methods'] = ['DELETE']
    return route(rule, **options)


# put 接口
def Put(rule: str, **options: any):
    options['methods'] = ['PUT']
    return route(rule, **options)


# 请求拦截器
after = blu.after_request
app_after = blu.after_app_request
error = blu.errorhandler
app_error = blu.app_errorhandler
before = blu.before_request
app_before = blu.before_app_request
formatParam = formatParam
R = R
Page = Page


def getUid():
    return JwtUtil.getUserId(request)


def getRid():
    return request.environ.get("RID")


def getUsername():
    return request.environ.get("USERNAME")


def getToken():
    token = request.headers.get('Authorization')
    if token is None:
        token = request.args.get('token')
    return token


# 查询参数格式化工具用于获取分页信息以及查询条件
def formatSelectInfo(need_param: list[str] = None):
    req = request
    if need_param is None:
        need_param = []
    page: Page = Page()
    cdn: dict = {}
    if req.method == 'Get':
        page.size = req.args.get('page_size') or 10
        page.num = req.args.get('page_num') or 1
        for item in need_param:
            cdn[item] = req.args.get(item) or None
    if req.method == 'POST':
        data: dict = request.json
        cdn = data.get('cdn') or {}
        page.size = data.get('size') or 10
        page.num = data.get('num') or 1
        for item in need_param:
            cdn[item] = req.args.get(item) or data.get(item)
    return page, cdn


# 获取用户真实ip地址
def getUserRemoteAddr():
    ip = request.headers.get('X-Real-IP')
    if ip is not None:
        return ip.replace('::ffff:', '').replace('::1', '127.0.0.1')
    ip = request.headers.get('X-Forwarded-For')
    if ip is not None:
        return ip.split(', ')[0].replace('::ffff:', '').replace('::1', '127.0.0.1')
    return request.remote_addr


def setSocket(s: SocketIO):
    global socket
    socket = s
